﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using produccion.clases;
using System.ComponentModel;
using produccion.AccesoDatos;
using System.Collections.ObjectModel;
using System.Windows.Input;
using System.Diagnostics;
using System.Collections.Specialized;
using System.Windows;
using System.Data;


namespace produccion.vistamodelo
{
    public class VMmantDaños : ViewModelBase, IDataErrorInfo
    {

        #region fields
        ProcesoProduccionRepositorio _repositorio = new ProcesoProduccionRepositorio();
        #endregion

        #region constructor

        public VMmantDaños()
        {
            consLisSecciones();
            lisDaños.CollectionChanged += OnCollectionChanged;

            if (MDOgeneral.conexion == null || MDOgeneral.conexion.State == ConnectionState.Closed)
            {
                MDOgeneral.conectar();
            }
            strTituloVentana = "Mantenimiento de daños - Usuario: " + MDOgeneral.usuario + " - [FRMmantDaños]";
        }
        
        #endregion

        #region metodos
       
        public void consLisSecciones(){
           try{
               lisSecciones = new CLSMAESEC().listarSecciones();
           }catch(Exception ex){msn.texto=ex.Message;msn.tipo=false;}
        }

        public void consultaDaños() {
            try {
                lisDaños.Clear();
                List<CLSTABDAN> listaDaños= _repositorio.ConsultaDaños(selSeccion);
                List<VMdaño> all=(from cust in listaDaños select new VMdaño(cust)).ToList();
                foreach (VMdaño cust in all) {
                    cust.validarCodRep += validarCodRep;
                    cust.PropertyChanged += OnPropertyChanged;
                }
                lisDaños = new ObservableCollection<VMdaño>(all);
                lisDaños.CollectionChanged += OnCollectionChanged;
              
            }
            catch (Exception ex) { msn.texto = ex.Message; msn.tipo = false;}
        }

        public void nuevoDaño() {
            try {

                lisDaños.Add(new VMdaño{agregar=true});
                
                 
            }
            catch (Exception ex) { msn.texto = ex.Message; msn.tipo = false; }
        }

        public string validarCodRep(string codigo) {
            int i = 0;
            try {
                 i=(from cust in lisDaños where cust.strCodigo.Trim().Equals(codigo.Trim()) select cust).ToList().Count();
                if (i >= 2) { return "El codigo ingresado ya existe."; }
            }
            catch (Exception ex) { msn.texto = ex.Message+i.ToString(); msn.tipo = true; 
           }
            return null;
        }

        void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            try
            {
                if (e.NewItems != null && e.NewItems.Count != 0)
                    foreach (VMdaño cust in e.NewItems)
                    {
                        cust.validarCodRep += validarCodRep;
                        cust.PropertyChanged += OnPropertyChanged;
                    }
                        
            }
            catch (Exception ex) { msn.texto = ex.Message; msn.tipo = false; }
        }

        void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
        {

            errorLisDaños = ((from cust in lisDaños where cust.IsValid.Equals(false) select cust.IsValid).ToList().Count()) > 0 ? true : false;
            
        }

        private bool _errorLisDaños = true;
        public bool errorLisDaños
        {
            get { return _errorLisDaños; }
            set
            {
                _errorLisDaños = value;
                base.OnPropertyChanged("errorLisDaños");
            }
        }

        #endregion

        #region public interface

        private string _strTituloVentana;
        public string strTituloVentana
        {
            get { return _strTituloVentana; }
            set { _strTituloVentana = value; base.OnPropertyChanged("strTituloVentana"); }
        }

        RelayCommand _cmdEliminar;
        public ICommand cmdEliminar
        {
            get
            {

                if (_cmdEliminar == null)
                {
                    _cmdEliminar = new RelayCommand(r => eliminarDaño());
                }
                return _cmdEliminar;
            }
        }


        RelayCommand _cmdGuardar;
        public ICommand cmdGuardar
        {
            get
            {

                if (_cmdGuardar == null)
                {
                    _cmdGuardar = new RelayCommand(r => GuardarDaño());
                }
                return _cmdGuardar;
            }
        }


        RelayCommand _cmdSalir;
        public ICommand cmdSalir
        {
            get
            {

                if (_cmdSalir == null)
                {
                    _cmdSalir = new RelayCommand(Salir);
                }
                return _cmdSalir;
            }
        }

        private void  Salir(object ventana)
        {
               try {
            ((Window)ventana).Close();
               }
               catch (Exception ex) { msn.texto = ex.Message; msn.tipo = false; }
        }

        private void GuardarDaño()
        {
            try {

                List<CLSTABDAN> agregar = (from cust in lisDaños where cust.agregar.Equals(true) select cust.getDaño()).ToList();
                List<CLSTABDAN> actualizar = (from cust in lisDaños where cust.actualizar.Equals(true) select cust.getDaño()).ToList();
                List<CLSTABDAN> eliminar = (from cust in lisDaños where cust.eliminar.Equals(true) select cust.getDaño()).ToList();

                if(_repositorio.GuardarDaños(actualizar,eliminar,agregar,selSeccion)){
                msn.texto="Los cambios fueron guardados exitosamente.";
                msn.tipo=true;
                consultaDaños();
                }else{
                   msn.texto="Los cambios no pueden ser guardados.";
                   msn.tipo=false;
                }

            }
            catch (Exception ex) { msn.texto = ex.Message; msn.tipo = false;
            System.Windows.MessageBox.Show(ex.Message);
            }
        }

        private void eliminarDaño()
        {
            try {

                if (selDaño.agregar)
                {
                    lisDaños.Remove(selDaño);
                }
                else {

                    selDaño.eliminar = !selDaño.eliminar;
                }
            }
            catch (Exception ex) { msn.texto = ex.Message; msn.tipo = false; }
        }

        private List<CLSMAESEC> _lisSecciones = new List<CLSMAESEC>();
        public List<CLSMAESEC> lisSecciones {
            get { return _lisSecciones;}
            set { _lisSecciones = value;
            base.OnPropertyChanged("lisSecciones");
            }
        }

        private CLSMAESEC _selSeccion;
        public CLSMAESEC selSeccion
        {
            get { return _selSeccion; }
            set
            {
                _selSeccion = value;
                if (_selSeccion != null) { consultaDaños(); }
                base.OnPropertyChanged("selSeccion");
            }
        }

        private MDOgeneral.mensaje _msn=new MDOgeneral.mensaje();
        public MDOgeneral.mensaje msn{
            get{return _msn;}
            set{_msn=value;
            base.OnPropertyChanged("msn");
            }
        }

        private ObservableCollection<VMdaño> _lisDaños = new ObservableCollection<VMdaño>();
        public ObservableCollection<VMdaño> lisDaños {
            get { return _lisDaños; }
            set { _lisDaños = value;
            base.OnPropertyChanged("lisDaños");
            }
        }


        private VMdaño _selDaño = new VMdaño();
        public VMdaño selDaño {
            get { return _selDaño; }
            set { _selDaño = value;
            base.OnPropertyChanged("selDaño");
            }
        
        }


        
        
        #endregion

        #region IDataErrorInfo Members

        string IDataErrorInfo.Error { get { return null; } }

        string IDataErrorInfo.this[string propertyName]
        {
            get { return this.GetValidationError(propertyName); }
        }

        #endregion

        #region Validation

        /// <summary>
        /// Returns true if this object has no validation errors.
        /// </summary>
        public bool IsValid
        {
            get
            {
                foreach (string property in ValidatedProperties)
                    if (GetValidationError(property) != null)
                        return false;

                return true;
            }
        }

        static readonly string[] ValidatedProperties = 
        { 
            "selSeccion"
                
        };

        string GetValidationError(string propertyName)
        {
            if (Array.IndexOf(ValidatedProperties, propertyName) < 0)
                return null;

            string error = null;

            switch (propertyName)
            {
                case "selSeccion":
                    error = this.validarselSeccion();
                    break;
           
                 default:
                    Debug.Fail("Unexpected property being validated on Customer: " + propertyName);
                 break;
            }

            return error;
        }

        private string validarselSeccion()
        {

            if (selSeccion == null) { return "Debe seleccionar una seccion."; }

            return null;
        }






        #endregion

    }

    public class VMdaño : ViewModelBase, IDataErrorInfo
    {

        #region fields
        private CLSTABDAN _daño=new CLSTABDAN();
        public delegate string validarCodRepetidos(string codigo);
        #endregion

        #region constructor
        public VMdaño(CLSTABDAN daño) {
            try {
                _daño = daño;
            }
            catch (Exception ex) { throw ex; }
        }
        public VMdaño()
        {
            agregar = true;
            
           

        }
        #endregion

        #region public interfaces

        public validarCodRepetidos validarCodRep;

        public string strCodigo 
        {
            get { return _daño.CODDAN_DAN; }
            set 
            {
                if (agregar == true)
                {
                    _daño.CODDAN_DAN = value;
                    base.OnPropertyChanged("strCodigo");
                }
            }
        }

        public string strNombre
        {
            get { return _daño.NOMDAN_DAN; }
            set
            {
                if (_daño.NOMDAN_DAN != value && agregar == false)
                    actualizar = true;
                _daño.NOMDAN_DAN = value;
                base.OnPropertyChanged("strNombre");
            }
        }

        public double numCosto 
        {
            get { return _daño.COSTO_DAN; }
            set 
            {
                if (_daño.COSTO_DAN != value && agregar == false)
                    actualizar = true;
                _daño.COSTO_DAN = value;
                base.OnPropertyChanged("numCosto");
            }
        }

        private bool _eliminar = false;
        public bool eliminar 
        {
            get { return _eliminar; }
            set { _eliminar = value; base.OnPropertyChanged("eliminar"); }
        }

        private bool _actualizar = false;
        public bool actualizar
        {
            get { return _actualizar; }
            set { _actualizar = value; base.OnPropertyChanged("actualizar"); }
        }

        private bool _agregar = false;
        public bool agregar
        {
            get { return _agregar; }
            set { _agregar = value; base.OnPropertyChanged("agregar"); }
        }



        #endregion

        #region IDataErrorInfo Members

        string IDataErrorInfo.Error { get { return null; } }

        string IDataErrorInfo.this[string propertyName]
        {
            get { return this.GetValidationError(propertyName); }
        }

        #endregion

        #region Validation

        /// <summary>
        /// Returns true if this object has no validation errors.
        /// </summary>
        public bool IsValid
        {
            get
            {
                foreach (string property in ValidatedProperties)
                    if (GetValidationError(property) != null)
                        return false;

                return true;
            }
        }

        static readonly string[] ValidatedProperties = 
        { 
            "strCodigo","strNombre","numCosto"
                
        };

        string GetValidationError(string propertyName)
        {
            if (Array.IndexOf(ValidatedProperties, propertyName) < 0)
                return null;

            string error = null;

            switch (propertyName)
            {
                case "strCodigo":
                    error = this.validarCodigo();
                    break;
                case "strNombre":
                    error = this.validarNombre();
                break;
                case "numCosto":
                error = this.validarCosto();
                break;

                    
                default:
                    Debug.Fail("Unexpected property being validated on Customer: " + propertyName);
                    break;
            }

            return error;
        }


        private string validarCodigo() 
        {
            //Codigo
            if (strCodigo == null) { return "El código del daño no puede estar vacio."; }
            if (strCodigo != null)
            {
                if (strCodigo.Length > 2) { return "El coódigo del daño máximo puede tener 2 caracteres."; }
                string error = validarCodRep(strCodigo);
                if (!String.IsNullOrEmpty(error))
                {
                    return error;
                }
            }
            return null;
        }

        private string validarNombre()
        {
            if (strNombre == null) { return "El nombre del daño no puede estar vacio."; }
            if (strNombre != null)
            {
                if (strNombre.Length > 50) { return "El nombre del daño máximo puede tener 50 caracteres."; }
            }

            return null;
        }

        private string validarCosto()
        {
            if (numCosto < 0) { return "El costo debe ser mayor o igual a 0"; }

            return null;
        }
        
    
        #endregion

        #region metodos
        public CLSTABDAN getDaño() {
            return _daño;
        }
        #endregion

    }

}
